package br.com.petsis.funcionalidades.manterUsuario;

import java.util.ArrayList;
import java.util.List;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;

import org.hibernate.mapping.Array;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.international.StatusMessage.Severity;

import br.com.petsis.entity.Cliente;
import br.com.petsis.entity.Empresa;
import br.com.petsis.entity.Perfil;
import br.com.petsis.entity.Usuario;
import br.com.petsis.utilitarios.UtilDate;
import br.com.petsis.utilitarios.UtilMail;
import br.com.petsis.utilitarios.UtilString;

@Name("manterUsuarioController")
@AutoCreate
@Scope(ScopeType.CONVERSATION)
public class ManterUsuarioController {
	
	private static final String QRY_USUARIOS = "select u from Usuario u where u.flgAtivo = 'T'";
	private static final String QRY_PERFIS = "select p from Perfil p where p.flgAtivo = 'T' and p.empresa is null";
	private static final String QRY_PERFIS_EMPRESA = "select p from Perfil p where p.flgAtivo = 'T' and p.empresa.idEmpresa = :idEmpresa";
	private static final String QRY_VALIDA_USUARIO = "select u from Usuario u where UPPER(u.dscUsuario) like UPPER(:usuario) and u.flgAtivo = 'T'";
	private static final String SENHA_PADRAO = "12345678";
	
	private static final String PARAMETER_USUARIO = "usuario";

	@In(create=true)
	private EntityManager entityManager;
	
	private List<Usuario> listaUsuarios;

	private boolean selecionadoTodos;
	
	private Usuario usuarioEdicao;
	
	private String confirmacaoSenha;
	
	private List<SelectItem> listaPerfis;
	
	private List<SelectItem> listaClientes;
	
	private Integer idPerfil;
	
	private Integer idCliente;
	
	@In(required=false)
	private Usuario usuarioLogado;
	
	@In(required=false)
	private Empresa empresaSessao;
	
	public void onLoad(){
		setListaClientes(null);
		setListaPerfis(null);
		setListaUsuarios(null);
		getListaClientes();
		getListaPerfis();
		getListaUsuarios();
	}
	
	public void novo(){
		getListaUsuarios().add(new Usuario());
	}
	
	public void cancelar(){
		usuarioEdicao = new Usuario();
		setIdPerfil(null);
	}
	
	public void salvarAlterarSenha(){
		if(!usuarioLogado.getDscSenha().equals(usuarioLogado.getConfirmacaoSenha())){
			FacesMessages.instance().add(Severity.ERROR,"A senha e a confirmação devem ser iguais.");
			return;
		}
		usuarioLogado.setDscSenha(UtilString.md5(usuarioLogado.getDscSenha()));
		usuarioLogado.setDtaUltimoAcesso(UtilDate.getDataAtual());
		entityManager.merge(usuarioLogado);
		entityManager.flush();
		FacesMessages.instance().add(Severity.INFO,"Senha alterada com sucesso.");
	}
	
	public void reiniciarSenha(){
		getUsuarioEdicao().setDscSenha(UtilString.md5(SENHA_PADRAO));
		getUsuarioEdicao().setDtaUltimoAcesso(null);
		entityManager.merge(getUsuarioEdicao());
		entityManager.flush();
		FacesMessages.instance().add(Severity.INFO,"Senha reiniciada com sucesso. A senha é "+SENHA_PADRAO);
	}
	                       
	public void salvar(){
		/*if(!usuarioEdicao.getDscSenha().equals(getConfirmacaoSenha())){
			FacesMessages.instance().add(Severity.ERROR,"A senha e a confirma��o devem ser iguais.");
			return;
		}*/
		if(getUsuarioEdicao().getIdUsuario() == null){
			getUsuarioEdicao().setEmpresa(empresaSessao);
		}
		
		if(getIdCliente() != null){
			Cliente cliente = entityManager.find(Cliente.class, getIdCliente());
			if(cliente != null){
				if(cliente.getDscEmail() == null || cliente.getDscEmail().isEmpty()){
					FacesMessages.instance().add(Severity.ERROR,"O cliente selecionado ainda não possui e-mail cadastrado.");
					return;
				}
			}
		}
		
		if(usuarioEdicao.getIdUsuario() == null){
			try{
				StringBuilder query = new StringBuilder(QRY_VALIDA_USUARIO);
				if(empresaSessao != null){
					query.append(" and u.empresa.idEmpresa = :idEmpresa");
				}
				
				Query qryResult = entityManager.createQuery(query.toString());
				
				if(empresaSessao != null){
					qryResult.setParameter("idEmpresa", empresaSessao.getIdEmpresa());	
				}
				qryResult.setParameter(PARAMETER_USUARIO, usuarioEdicao.getDscUsuario());
				qryResult.getSingleResult();
				FacesMessages.instance().add(Severity.ERROR,"Já existe um usuário salvo com esse nome");
				return;
			}catch(NoResultException n){
				usuarioEdicao.setDscSenha(UtilString.md5(SENHA_PADRAO));
				setListaUsuarios(null);
				usuarioEdicao.setCliente(getIdCliente() != null ? entityManager.find(Cliente.class, getIdCliente()): null);
				usuarioEdicao.setPerfil(entityManager.find(Perfil.class, getIdPerfil()));
				entityManager.merge(usuarioEdicao);
				entityManager.flush();
				usuarioEdicao = new Usuario();
				setIdPerfil(null);
				setIdCliente(null);
				FacesMessages.instance().add(Severity.INFO,"Usuário salvo com sucesso. A senha inicial é "+SENHA_PADRAO);
			}
		}else{
			setListaUsuarios(null);
			usuarioEdicao.setCliente(getIdCliente() != null ? entityManager.find(Cliente.class, getIdCliente()): null);
			usuarioEdicao.setPerfil(entityManager.find(Perfil.class, getIdPerfil()));
			entityManager.merge(usuarioEdicao);
			entityManager.flush();
			usuarioEdicao = new Usuario();
			setIdPerfil(null);
			setIdCliente(null);
			FacesMessages.instance().add(Severity.INFO,"Usuário salvo com sucesso.");
		}
	}
	
	public void selecionaTodos(ValueChangeEvent evento){
		selecionadoTodos = (Boolean)evento.getNewValue();
		for(Usuario u : getListaUsuarios()){
			if(isSelecionadoTodos()){
				u.setSelecionado(true);
			}else{
				u.setSelecionado(false);
			}
		}
	}

	public List<Usuario> getListaUsuarios() {
		if (listaUsuarios == null) {
			StringBuilder query = new StringBuilder(QRY_USUARIOS);
			
			if(empresaSessao != null){
				query.append(" and u.empresa.idEmpresa = :idEmpresa");
			}
			
			Query qryResult = entityManager.createQuery(query.toString());
			
			if(empresaSessao != null){
				qryResult.setParameter("idEmpresa", empresaSessao.getIdEmpresa());
			}
			
			listaUsuarios = qryResult.getResultList(); 
		}
		return listaUsuarios;
	}

	public void setListaUsuarios(List<Usuario> listaUsuarios) {
		this.listaUsuarios = listaUsuarios;
	}

	public boolean isSelecionadoTodos() {
		return selecionadoTodos;
	}

	public void setSelecionadoTodos(boolean selecionadoTodos) {
		this.selecionadoTodos = selecionadoTodos;
	}

	public Usuario getUsuarioEdicao() {
		if (usuarioEdicao == null) {
			usuarioEdicao = new Usuario();
		}
		return usuarioEdicao;
	}

	public void setUsuarioEdicao(Usuario usuarioEdicao) {
		this.usuarioEdicao = usuarioEdicao;
	}

	public String getConfirmacaoSenha() {
		return confirmacaoSenha;
	}

	public void setConfirmacaoSenha(String confirmacaoSenha) {
		this.confirmacaoSenha = confirmacaoSenha;
	}
	
	public void excluir(){
		List<Usuario> usuariosRemocao = new ArrayList<Usuario>();
		for(Usuario u : getListaUsuarios()){
			if(u.isSelecionado()){
				usuariosRemocao.add(u);
			}
		}
		getListaUsuarios().removeAll(usuariosRemocao);
		for(Usuario user : usuariosRemocao){
			entityManager.remove(user);
		}
		entityManager.flush();
		FacesMessages.instance().add(Severity.INFO,"Usuário(s) excluído(s) com sucesso.");
	}
	
	public void editar(Usuario usuario){
		usuarioEdicao = usuario;
		setIdCliente(usuario.getCliente() != null ? usuario.getCliente().getIdCliente() : null);
		setIdPerfil(usuario.getPerfil().getIdPerfil());
	}

	public List<SelectItem> getListaPerfis() {
		if (listaPerfis == null) {
			listaPerfis = new ArrayList<SelectItem>();
			listaPerfis.add(new SelectItem(null,"Selecione"));
			List<Perfil> lista = new ArrayList<Perfil>();
			if(empresaSessao != null){
				lista = entityManager.createQuery(QRY_PERFIS_EMPRESA)
					.setParameter("idEmpresa", empresaSessao.getIdEmpresa())
					.getResultList();
			}else{
				lista = entityManager.createQuery(QRY_PERFIS).getResultList();
			}
			for(Perfil p : lista){
				listaPerfis.add(new SelectItem(p.getIdPerfil(),p.getDscNome()));
			}
		}
		return listaPerfis;
	}

	public void setListaPerfis(List<SelectItem> listaPerfis) {
		this.listaPerfis = listaPerfis;
	}

	public List<SelectItem> getListaClientes() {
		if (listaClientes == null) {
			listaClientes = new ArrayList<SelectItem>();
			listaClientes.add(new SelectItem(null,"Selecione"));
			List<Cliente> lista = new ArrayList<Cliente>();
			if(empresaSessao != null){
				lista = entityManager.createQuery("select c from Cliente c where c.flgAtivo = 'T' and c.empresa.idEmpresa = :idEmpresa order by c.dscNome")
					.setParameter("idEmpresa", empresaSessao.getIdEmpresa())
					.getResultList();
			}else{
				lista = entityManager.createQuery("select c from Cliente c where c.flgAtivo = 'T' order by c.dscNome")
					.getResultList();
			}
			for (Cliente cliente : lista) {
				listaClientes.add(new SelectItem(cliente.getIdCliente(), cliente.getDscNome()));
			}
		}
		return listaClientes;
	}

	public void setListaClientes(List<SelectItem> listaClientes) {
		this.listaClientes = listaClientes;
	}

	public Integer getIdPerfil() {
		return idPerfil;
	}

	public void setIdPerfil(Integer idPerfil) {
		this.idPerfil = idPerfil;
	}

	public Integer getIdCliente() {
		return idCliente;
	}

	public void setIdCliente(Integer idCliente) {
		this.idCliente = idCliente;
	}
	
}
